# import json
# import xml.dom.minidom
# from xml.dom import minidom
#
# import xml.etree.ElementTree as ET
import xml.dom.minidom
from xml.dom.minidom import parse
#
# from jmeter_api.basics.config.elements import BasicConfig
# from jmeter_api.basics.listener.elements import ResultCollector
# from jmeter_api.basics.sampler.elements import UserDefinedVariables
# from jmeter_api.configs import HTTPCookieManager
# from jmeter_api.configs.http_cache_manager.elements import HTTPCacheManager
# from jmeter_api.configs.http_cookie_manager.elements import Cookie
# from jmeter_api.configs.user_defined_variables.elements import Argument, UserDefineVariables
# from jmeter_api.listeners import ViewResultsTree, BackendListener
# from jmeter_api.pre_processors import JSR223PreProcessor
# from jmeter_api.timers.constant_throughput_timer.elements import ConstantThroughputTimer
# from jmeter_api.timers.constant_timer.elements import ConstantTimer
import importlib
import json
import yaml
# from jmeter_api.non_test_elements.test_plan.elements import TestPlan

import jmespath

from config_params.assertions import Assertions
from config_params.config_element import ConfigElement
from config_params.listeners import Listeners
from config_params.preProcessor import PreProcessor
from config_params.samplers import Samplers
from config_params.threads import Threads
from config_params.timer import Timer
from jmeter_api.samplers.http_request.elements import HttpRequest

# from jmeter_api.controllers.loop_controller.elements import LoopController
# from jmeter_api.test_fragment.elements import TestFragment
# from jmeter_api.controllers.module_controller.elements import ModuleController
# from jmeter_api.config_params.http_request.elements import HttpRequest
# from jmeter_api.config_params.jsr223.elements import JSR223
# from jmeter_api.thread_groups.common_thread_group.elements import CommonThreadGroup
#
# if __name__ == "__main__":
#     test_plan = TestPlan(name='NewTestPlan',is_enabled=False)
#     test_plan.variables = {"name":"张珊","age":"12"}
#     test_plan.append(HTTPCacheManager(clear_each_iteration=True))
#     test_plan.append(ViewResultsTree())
#     test_plan.append(BackendListener())
#     test_plan.append(UserDefineVariables(arguments=[Argument(name=f'var{i}', value=f'12{i}') for i in range(5)], comments="fjdsafjkldj", name="anxiaodong"))
#     test_plan.append(HTTPCookieManager(cookies=[Cookie(name="a",value="1")],comments="header1111"))
#     h1 = HttpRequest(host='www.google.com')
#     # h1.add_user_variable(UserDefinedVariables(name="a",value="1"), UserDefinedVariables(name="b",value="2"),UserDefinedVariables(name="b",value="2"))
#     s1 = {
#         "a":1,
#         "b":"2"
#     }
#     h1.text=json.dumps(s1,indent=2)
#     test_plan.append(CommonThreadGroup(continue_forever=True, name='FirstThreadGroup')
#                      .append(h1)
#                      .append(JSR223PreProcessor(name="jsr23345",script='System.out.print("hello world")'))
#                      .append(UserDefineVariables(arguments=[Argument(name='var', value='12')]))
#                      .append(ConstantTimer(delay=1000))
#                      )
# second_thread_group = CommonThreadGroup(
#     continue_forever=True, name='SecondThreadGroup')
# for x in range(20):
#     second_thread_group.append(HttpRequest(
#         host='www.google.com', path=f'/new-{x}', name=f'NewSampler{x}'))
# second_thread_group.append(ConstantThroughputTimer(targ_throughput=10))
# test_plan.append(second_thread_group)
#
# test_fragment = TestFragment()
#
# lc = LoopController(loops=3, name='loop3')
# lc2 = LoopController(continue_forever=True)
# lc2.append(HttpRequest(host='www.google.com'))
# lc.append(HttpRequest(host='www.google.com'))
# lc.append(lc2)
# mc = ModuleController(node_path="NewTestPlan/Test Fragment/loop3")
# test_fragment.append(lc)
# test_fragment.append(mc)
# test_plan.append(test_fragment)

# open('example_testplan_01.jmx', 'w').write(test_plan.to_xml())
# index = __import__('jmeter_api.non_test_elements.test_plan.elements', fromlist=("TestPlan",))
# test_plan = index.TestPlan()

# module_class = {
#     "TestPlan": "jmeter_api.non_test_elements.test_plan.elements",
#     "ThreadGroupAction": "jmeter_api.basics.thread_group.elements",
#     "HTTPCacheManager": "jmeter_api.configs.http_cache_manager.elements",
#     "CommonThreadGroup": "jmeter_api.thread_groups.common_thread_group.elements"
# }


# def create_instance(class_name, params_dict: dict = {}):
#     modules = __import__(f"{module_class.get(class_name)}", fromlist=(class_name,))
#     return modules.__dict__.get(class_name)(**params_dict)
#
#
# def get_instance_attr(class_name):
#     modules = __import__(f"{module_class.get(class_name)}", fromlist=(class_name,))
#     return modules.__dict__.get(class_name)

class generJmeterXml:
    data = ""
    test_plan = {}
    threads_dict = {}

    def jme_path(self, exp, data):
        return jmespath.search(exp, data)

    def generate(self, file_name):
        with open(file_name, "r", encoding="utf-8") as f:
            res_list = yaml.safe_load(f)
            res = res_list["jmeterTestPlan"]
            test_plan = Threads(res).test_plan()
            for k, v in res["testPlan"].items():
                self.data = res
                if k == "configElement":
                    self.config_element(test_plan, self.jme_path("testPlan.configElement", res))
                elif k == "listeners":
                    self.listeners(test_plan, self.jme_path("testPlan.listeners", res))
                elif k == "threadGroup":
                    self.threads(test_plan, self.jme_path("testPlan.threadGroup", res))
                elif k == "ConcurrencyThreadGroup":
                    self.threads(test_plan, self.jme_path("testPlan.ConcurrencyThreadGroup", res))
                elif k == "timer":
                    self.timer(test_plan, self.jme_path("testPlan.timer", res))
                elif k == "preProcessor":
                    self.preProcessor(test_plan, self.jme_path("testPlan.preProcessor",res))
            with open('example_testplan_06.jmx', 'w', encoding="utf-8") as f:

                dom = xml.dom.minidom.parseString(test_plan.to_xml())
                pretty_xml = dom.toprettyxml(indent="  ")
                pretty_xml = '\n'.join([line for line in pretty_xml.split('\n') if line.strip()])
                f.write(pretty_xml)

    def config_element(self,test_plan, config_elements):
        if config_elements is not None and len(config_elements) > 0:
            for config_element in config_elements:
                data = config_element
                config_elements_list = ConfigElement(data).configElement()
                for config_element_obj in config_elements_list:
                    test_plan.append(config_element_obj)

    def listeners(self, test_plan, listeners):
        if listeners is not None and len(listeners) > 0:
            for listener in listeners:
                data = listener
                listeners_list = Listeners(data).listeners()
                for listener in listeners_list:
                    test_plan.append(listener)
    def preProcessor(self, test_plan, preProcessors):
        if preProcessors is not None and len(preProcessors) > 0:
            for preProcessor in preProcessors:
                preProcessors_list = PreProcessor(preProcessor).preProcessor()
                for preProcessor in preProcessors_list:
                    test_plan.append(preProcessor)

    def timer(self, test_plan, timers):
        if timers is not None and len(timers) > 0:
            for timer in timers:
                data = timer
                timers_list = Timer(data).timer()
                for timer in timers_list:
                    test_plan.append(timer)

    def threads(self, test_plan, threads):
        if threads is not None and len(threads) > 0:
            for thread in threads:
                threads_list = Threads(thread).threads()
                for thread_obj in threads_list:
                    if self.jme_path("samplers",thread) is not None:
                        self.samplers(thread_obj, self.jme_path("samplers",thread))
                    test_plan.append(thread_obj)

    def samplers(self, thread_obj, samplers):
        if samplers is not None and len(samplers) > 0:
            for sampler in samplers:
                samplers_list = Samplers(sampler).sampler()
                for samp in samplers_list:
                    if self.jme_path("assertions", sampler) is not None:
                        self.assertions(samp, self.jme_path("assertions", sampler))
                    if self.jme_path("timer", sampler) is not None:
                        self.timer(samp, self.jme_path("timer", sampler))
                    if self.jme_path("listeners", sampler) is not None:
                        self.listeners(samp, self.jme_path("listeners", sampler))
                    if self.jme_path("preProcessor", sampler) is not None:
                        self.preProcessor(samp, self.jme_path("preProcessor", sampler))
                    thread_obj.append(samp)

    def assertions(self, samp, assertions):
        if assertions is not None and len(assertions) > 0:
            for assertion in assertions:
                assertions_list = Assertions(assertion).assertion()
                for assertion_obj in assertions_list:
                    samp.append(assertion_obj)


gen = generJmeterXml()
gen.generate("/Users/anxiaodong/PycharmProjects/jmeter-api/jmeter_demo.yaml")